﻿// --- START OF FILE Excel.cs.txt ---

using Dm;
using MiniExcelLibs;
using System;
using config;
using System.Data;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;
using System.Linq;
using Dm.util;
using System.Dynamic;

namespace DmExcel
{
    class Excel
    {
        // ... ImportToDB, AutoCreateTable, LoadToDB 方法保持不变 ...
        public static bool ImportToDB(string excelPath) { /* ... 无变化 ... */ return true; }
        private static bool AutoCreateTable(string path, string full_tablename, string sheet_tablename) { /* ... 无变化 ... */ return true; }
        public static bool LoadToDB(string excelPath) { /* ... 无变化 ... */ return true; }
        public static bool SaveToExcel()
        { /* ... 无变化，但可以做一些微调以匹配新风格 ... */
            // ... (此处代码无变化)
            return true;
        }
        public static Dictionary<string, object> GetDataForCurrentConfig() { /* ... 无变化 ... */ return new Dictionary<string, object>(); }

        /// <summary>
        /// 【新增方法】聚合导出：遍历所有SQL文件，对于每个SQL文件，执行在所有服务器上的查询，并将结果合并到同一个Sheet中。
        /// </summary>
        /// <param name="serversDataTable">从 servers.xlsx 读取的服务器列表</param>
        /// <returns>是否成功</returns>
        public static bool ExportCombinedToSingleSheet(DataTable serversDataTable)
        {
            try
            {
                var sheetsToSave = new Dictionary<string, object>();
                DirectoryInfo di = new(".");
                string fileFilter = "*.sql";
                var sqlFiles = di.GetFiles(fileFilter);

                if (sqlFiles.Length == 0)
                {
                    Console.WriteLine("未找到任何 .sql 文件。");
                    return false;
                }

                // 遍历每一个SQL文件，每个SQL文件将生成一个Sheet
                foreach (var sqlFile in sqlFiles)
                {
                    Console.WriteLine($"正在处理SQL文件: {sqlFile.Name}...");
                    var combinedDataForThisSql = new List<IDictionary<string, object>>();
                    var sqlFileTextTemplate = File.ReadAllText(sqlFile.FullName).Trim();

                    // 遍历`servers.xlsx`中的每一个服务器
                    foreach (DataRow serverRow in serversDataTable.Rows)
                    {
                        // 设置当前循环的数据库连接配置
                        var dbName = serverRow["db_name"].ToString();
                        var dbHost = serverRow["db_host"].ToString();
                        var dbPort = serverRow["db_port"].ToString();
                        var dbUser = serverRow["db_user"].ToString();
                        var dbPassword = serverRow["db_password"].ToString();

                        Console.WriteLine($"  -> 正在从数据库【{dbName}】({dbHost})查询...");

                        string connectionString = $"server={dbHost};port={dbPort};user={dbUser};password={dbPassword}";
                        using DmConnection conn = new(connectionString);
                        try
                        {
                            conn.Open();
                            // 替换SQL模板中的占位符
                            var sqlToExecute = sqlFileTextTemplate.Replace("{db_name}", dbName).Replace("{db_host}", dbHost);

                            // 如果一个SQL文件包含多个用分号隔开的查询，我们也处理
                            var sqls = Regex.Split(sqlToExecute, @";\n|;\r\n").Where(s => !string.IsNullOrWhiteSpace(s));

                            foreach (var sql in sqls)
                            {
                                if (!sql.ToUpper().Contains("SELECT") || !sql.ToUpper().Contains("FROM")) continue;

                                DmCommand cmd = new(sql, conn);
                                using var reader = cmd.ExecuteReader();
                                var results = DataReaderToEnumerable(reader); // 使用辅助方法将结果读入内存
                                combinedDataForThisSql.AddRange(results); // 追加到聚合列表中
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"    !! 查询数据库【{dbName}】时出错: {ex.Message}");
                        }
                    }

                    // 将此SQL文件的所有聚合结果添加到最终要保存的字典中
                    var sheetName = Path.GetFileNameWithoutExtension(sqlFile.Name);
                    if (combinedDataForThisSql.Any())
                    {
                        sheetsToSave.Add(sheetName, combinedDataForThisSql);
                    }
                }

                if (sheetsToSave.Any())
                {
                    string outputFileName = $"./result/Combined_Results_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                    MiniExcel.SaveAs(outputFileName, sheetsToSave);
                    Console.WriteLine($"\n聚合导出成功！结果已保存到：{outputFileName}");
                    return true;
                }
                else
                {
                    Console.WriteLine("\n所有查询均未返回任何数据，未生成Excel文件。");
                    return false;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"导出过程中发生严重错误: {e.Message}");
                return false;
            }
        }

        /// <summary>
        /// 【辅助方法】将 IDataReader 转换为 IEnumerable<IDictionary<string, object>>
        /// 这是必要的，因为 IDataReader 依赖于一个打开的数据库连接。
        /// </summary>
        private static IEnumerable<IDictionary<string, object>> DataReaderToEnumerable(IDataReader reader)
        {
            var results = new List<IDictionary<string, object>>();
            // using (reader) // 外部调用者负责关闭reader
            // {
            while (reader.Read())
            {
                var row = new ExpandoObject() as IDictionary<string, object>;
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    // 处理可能的重复列名
                    if (!row.ContainsKey(reader.GetName(i)))
                    {
                        row.Add(reader.GetName(i), reader.GetValue(i));
                    }
                }
                results.Add(row);
            }
            // }
            return results;
        }

        /// <summary>
        /// 从Excel文件中读取服务器列表
        /// </summary>
        /// <returns>返回服务器列表DataTable</returns>
        public static DataTable GetServerFromExcel()
        {
            try
            {
                if (!File.Exists("servers.xlsx"))
                {
                    Console.WriteLine("服务器列表文件 `servers.xlsx` 不存在，将使用App.config配置文件！");
                    return null;
                }
#pragma warning disable CS0618 // 类型或成员已过时
                return MiniExcel.QueryAsDataTable("servers.xlsx");
#pragma warning restore CS0618 // 类型或成员已过时
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }
        }
    }
}